package com.ravi.common.exception;

import com.ravi.common.constant.CheckExceptionEnum;
import com.ravi.model.resp.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

/**
 * 统一处理全局异常
 */
@ControllerAdvice
public class GlobalExceptionHandler {
	private final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	@ExceptionHandler(Exception.class)
	@ResponseBody
	public Object handleException(Exception e) {
		logger.error("Deafult Exception: ", e);
		return R.error(CheckExceptionEnum.SYSTEM_ERROR);
	}

	@ExceptionHandler(CheckException.class)
	@ResponseBody
	public Object handleRaviMallException(CheckException e) {
		logger.error("CheckException: ", e);
		return R.error(e.getCode(), e.getMessage());
	}

	@ExceptionHandler(MethodArgumentNotValidException.class)
	@ResponseBody
	public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
		logger.error("MethodArgumentNotValidException: ", e);

		return handleBindingResult(e.getBindingResult());
	}

	private R handleBindingResult(BindingResult result) {
		// 把异常处理为对外暴露的提示
		List<String> list = new ArrayList<>();
		if (result.hasErrors()) {
			List<ObjectError> allErrors = result.getAllErrors();
			for (ObjectError error : allErrors) {
				String message = error.getDefaultMessage();
				list.add(message);
			}
		}

		if (list.size() == 0) {
			return R.error(CheckExceptionEnum.REQUEST_PARAM_ERROR);
		}

		return R.error(CheckExceptionEnum.REQUEST_PARAM_ERROR.getCode(),
				list.toString());
	}
}